package com.eversec.util.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.eversec.util.command.CharacterEnding;

public class FileRead {

	/**
	 * 以字节为单位读取文件，常用于读二进制文件，如图片、声音、影像等文件。
	 */
	public static void readFileByBytes(String fileName) {
		File file = new File(fileName);
		InputStream in = null;
		try {
			System.out.println("以字节为单位读取文件内容，一次读一个字节：");
			// 一次读一个字节
			in = new FileInputStream(file);
			int tempbyte;
			while ((tempbyte = in.read()) != -1) {
				System.out.write(tempbyte);
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		try {
			System.out.println("以字节为单位读取文件内容，一次读多个字节：");
			// 一次读多个字节
			byte[] tempbytes = new byte[100];
			int byteread = 0;
			in = new FileInputStream(fileName);
			FileRead.showAvailableBytes(in);
			// 读入多个字节到字节数组中，byteread为一次读入的字节数
			while ((byteread = in.read(tempbytes)) != -1) {
				System.out.write(tempbytes, 0, byteread);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e1) {
				}
			}
		}
	}

	/**
	 * 以字符为单位读取文件，常用于读文本，数字等类型的文件
	 */
	public static String readFileByChars(String fileName) {
		StringBuffer sb = new StringBuffer();
		File file = new File(fileName);
		Reader reader = null;
		try {
			// System.out.println("以字符为单位读取文件内容，一次读一个字节：");
			// 一次读一个字符
			reader = new InputStreamReader(new FileInputStream(file));
			int tempchar;
			while ((tempchar = reader.read()) != -1) {
				// 对于windows下，\r\n这两个字符在一起时，表示一个换行。
				// 但如果这两个字符分开显示时，会换两次行。
				// 因此，屏蔽掉\r，或者屏蔽\n。否则，将会多出很多空行。
				if (((char) tempchar) != '\r') {
					// System.out.print((char) tempchar);
					sb.append(tempchar);
				}
			}
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			System.out.println("以字符为单位读取文件内容，一次读多个字节：");
			// 一次读多个字符
			char[] tempchars = new char[30];
			int charread = 0;
			reader = new InputStreamReader(new FileInputStream(fileName));
			// 读入多个字符到字符数组中，charread为一次读取字符数
			while ((charread = reader.read(tempchars)) != -1) {
				// 同样屏蔽掉\r不显示
				if ((charread == tempchars.length) && (tempchars[tempchars.length - 1] != '\r')) {
					System.out.print(tempchars);
				} else {
					for (int i = 0; i < charread; i++) {
						if (tempchars[i] == '\r') {
							continue;
						} else {
							System.out.print(tempchars[i]);
						}
					}
				}
			}

		} catch (Exception e1) {
			e1.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return null;
	}

	/**
	 * 以行为单位读取文件，常用于读面向行的格式化文件
	 */
	public static String readFileByLines(String fileName) {
		StringBuffer sb = new StringBuffer();
		File file = new File(fileName);
		BufferedReader reader = null;
		try {
			// System.out.println("以行为单位读取文件内容，一次读一整行：");
			String encoding = CharacterEnding.getFileCharacterEnding(file);
			reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), encoding));
			String tempString = null;
			// 一次读入一行，直到读入null为文件结束
			while ((tempString = reader.readLine()) != null) {
				sb.append(tempString);
			}
			return sb.toString();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return null;
	}

	/**
	 * 随机读取文件内容
	 */
	public static void readFileByRandomAccess(String fileName) {
		RandomAccessFile randomFile = null;
		try {
			System.out.println("随机读取一段文件内容：");
			// 打开一个随机访问文件流，按只读方式
			randomFile = new RandomAccessFile(fileName, "r");
			// 文件长度，字节数
			long fileLength = randomFile.length();
			// 读文件的起始位置
			int beginIndex = (fileLength > 4) ? 4 : 0;
			// 将读文件的开始位置移到beginIndex位置。
			randomFile.seek(beginIndex);
			byte[] bytes = new byte[10];
			int byteread = 0;
			// 一次读10个字节，如果文件内容不足10个字节，则读剩下的字节。
			// 将一次读取的字节数赋给byteread
			while ((byteread = randomFile.read(bytes)) != -1) {
				System.out.write(bytes, 0, byteread);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (randomFile != null) {
				try {
					randomFile.close();
				} catch (IOException e1) {
				}
			}
		}
	}

	/**
	 * 显示输入流中还剩的字节数
	 */
	private static void showAvailableBytes(InputStream in) {
		try {
			System.out.println("当前字节输入流中的字节数为:" + in.available());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * A方法追加文件：使用RandomAccessFile
	 */
	public static void appendMethodA(String fileName, String content) {
		try {
			// 打开一个随机访问文件流，按读写方式
			RandomAccessFile randomFile = new RandomAccessFile(fileName, "rw");
			// 文件长度，字节数
			long fileLength = randomFile.length();
			// 将写文件指针移到文件尾。
			randomFile.seek(fileLength);
			randomFile.writeBytes(content);
			randomFile.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * B方法追加文件：使用FileWriter
	 */
	public static void appendMethodB(String fileName, String content) {
		try {
			// 打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
			FileWriter writer = new FileWriter(fileName, true);
			writer.write(content);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 遍历文件夹里的内容
	 */
	public static List<String> refreshFileList(String strPath, List<String> fileList) {

		File dir = new File(strPath);
		File[] files = dir.listFiles();
		if (files == null)
			return null;
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				refreshFileList(files[i].getAbsolutePath(), fileList);
			} else {
				fileList.add(files[i].getAbsolutePath());
			}
		}
		return fileList;
	}

	/**
	 * 查询某个目录下的所有文件
	 */
	public static List<String> getAllFile(String strPath) {
		List<String> fileList = new ArrayList<String>();
		return refreshFileList(strPath, fileList);
	}

	/**
	 * 得到文件的文件名
	 */
	public static String getFileName(String fileName) {
		if (fileName != null && fileName.contains("/")) {
			return fileName.substring(fileName.lastIndexOf("/") + 1);
		} else {
			return fileName;
		}
	}

	/**
	 * 得到文件的后缀名
	 */
	public static String getFileSuffix(String fileName) {
		if (StringUtils.isNotBlank(fileName)) {
			int index = fileName.lastIndexOf(".");
			if (index != -1 && (index < fileName.length() - 1)) {
				return fileName.substring(index + 1);
			}
		}
		return "";
	}

	public static void main(String[] args) {
		renameFileStuffix("D:/idcTest/ftp/01/13348216593272.xml", ".ok");
	}

	// /**
	// * 得到文件的后缀名 ，参数为文件名
	// */
	// public static String getFileSuffix2(String fileName){
	// String[] fileNameArray = fileName.split("\\.");
	// return fileNameArray[fileNameArray.length - 1];
	// }

	/**
	 * 重命名文件后缀名为.xml
	 */
	public static void renameFileStuffix(String filePath, String stuffix) {
		File file = new File(filePath);
		file.renameTo(new File(filePath + stuffix));
	}

	/**
	 * 遍历文件，得到特定后缀名的文件
	 */
	public static List<String> getMyFile(String filePath, String stuffixType) {
		List<String> fileNameList = new ArrayList<String>();
		List<String> fileList = new ArrayList<String>();
		// 遍历某个目录下的所有文件
		fileNameList = refreshFileList(filePath, fileNameList);
		// 得到指定后缀名的文件
		if (fileNameList != null && fileNameList.size() > 0) {
			for (String fpath : fileNameList) {
				String fileSuffix = FileRead.getFileSuffix(fpath);
				if (fileSuffix != null && fileSuffix.equals(stuffixType)) {
					fileList.add(fpath);
				}
			}
		}
		return fileList;
	}

	/**
	 * 遍历文件，得到所有匹配文件文件名的文件
	 */
	public static List<String> getMyFileName(String filePath, String myFileName) {
		List<String> fileNameList = new ArrayList<String>();
		List<String> list = new ArrayList<String>();

		// 遍历某个目录下的所有文件
		List<String> fileList = refreshFileList(filePath, fileNameList);
		// 得到指定后缀名的文件
		if (fileList != null) {
			for (String fpath : fileList) {
				File file = new File(fpath);
				if (file != null) {
					String fileName = file.getName();
					if (fileName != null && fileName.equals(myFileName)) {
						list.add(fpath);
					}
				}
			}
			return list;
		} else {
			return new ArrayList<String>();
		}
	}

	/**
	 * 遍历文件，得到所有文件名以特定名称开头的文件
	 * 
	 * @param filePath
	 * @param myFileName
	 * @return
	 */
	public static List<String> getMyFileBySubName(String filePath, String stuffixType) {
		List<String> fileNameList = new ArrayList<String>();
		List<String> list = new ArrayList<String>();

		// 遍历某个目录下的所有文件
		List<String> fileList = refreshFileList(filePath, fileNameList);
		// 得到指定后缀名的文件
		if (fileList != null) {
			for (String fpath : fileList) {
				String fileSuffix = FileRead.getFileSuffix(fpath);
				if (fileSuffix != null && stuffixType.contains(fileSuffix)) {
					list.add(fpath);
				}
			}
			return list;
		} else {
			return new ArrayList<String>();
		}
	}

}
